package cn.xuqiudong.backend.config.satoken;

import cn.dev33.satoken.stp.StpInterface;
import cn.xuqiudong.backend.base.helper.SaSessionHelper;
import cn.xuqiudong.backend.base.helper.SessionUserInfo;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 描述:
 * sa-token 中的用户角色和用户权限:
 * 如此可以使用 : @SaCheckPermission("user:add")   @SaCheckRole("admin")等注解
 *
 * 本项目依赖于login之后存入用户信息到session，所以需要从session中获取角色和权限
 * 但是会缓存到本地 Caffeine， 当用户小心变化的时候，可手动调用 cleanCache()
 * TODO 集群下，暂未处理其他JVN下的缓存失效，后续考虑加入redis发布订阅
 *
 * @author Vic.xu
 * @see SaSessionHelper#storeUser(SessionUserInfo)
 * @since 2025-03-10 9:48
 */
@Component
public class StpInterfaceImpl implements StpInterface {
    // 本地缓存初始化
    private static Cache<String, List<String>> roleCache = Caffeine.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();

    private static Cache<String, List<String>> permissionCache = Caffeine.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();

    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        String key = loginId.toString();
        return roleCache.get(key, k -> fetchRolesFromSession(loginId));
    }

    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        String key = loginId.toString();
        return permissionCache.get(key, k -> fetchPermissionsFromSession(loginId));
    }

    public List<String> fetchRolesFromSession(Object loginId) {
        List<String> roles = SaSessionHelper.getRoles();
        return roles == null ? new ArrayList<>() : roles;
    }

    public List<String> fetchPermissionsFromSession(Object loginId) {
        List<String> permissions = SaSessionHelper.getPermissions();
        return permissions == null ? new ArrayList<>() : permissions;
    }

    /**
     * 清理缓存
     */
    public static void cleanCache(){
        roleCache.invalidateAll();
        permissionCache.invalidateAll();
    }




}